"""An online chat robot for knowledge based question answering.

It's a interface which receives questions from user and makes responses one by one.
In addition, you can define your own module and fill the respective slot.

    Typical usage example:

    robot = Robot(
        filter_slot=None,
        analyze_slot=None,
        link_slot=your own LinkSlot instance or None,
        query_slot=None,
        answer_slot=None
    )
    response = robot.request('your first question here')
    response = robot.request('your second question here')
"""

from kbqa.question_answer import *


class Robot(object):
    """An easy-to-expand chatbot agent

    Attributes:
        filter_slot: (FilterSlot) filter invalid words in question
        analyze_slot: (AnalyzeSlot) anlyze the question, for example, recognize named entities
        link_slot: (LinkSlot) link phrases and entities to the knowledge base
        query_slot: (QuerySlot) generate sparql query
        answer_slot: (AnswerSlot) generate answers according to query results
    """

    def __init__(self, filter_slot=None, analyze_slot=None, link_slot=None, query_slot=None, answer_slot=None):
        """Use some slots to generate a robot

        Just fill the slot your want to rewrite and ignore the other slots.
        Every 'None' slot will get a default initialization.
        """
        self.filter_slot = filter_slot if filter_slot is not None else FilterSlot()
        self.analyze_slot = analyze_slot if analyze_slot is not None else AnalyzeSlot()
        self.link_slot = link_slot if link_slot is not None else LinkSlot()
        self.query_slot = query_slot if query_slot is not None else QuerySlot()
        self.answer_slot = answer_slot if analyze_slot is not None else AnswerSlot()

    def request(self, question, dialogue_id):
        """Receive a question from user and return a response to user.

            For example:

            question = '台风的英文名是什么？'
            dialogue_id = '2020031321-01J'
            response = '台风的英文名是Typhoon.'
        
        Args:
            question (str): Question from user.
            dialogue_id (str): Distinguish between different groups of dialogues.
        
        Returns:
            A string response answering to this question.
        """
        filterd_question = self.filter_slot.handle(question)
        analyzed_question = self.analyze_slot.handle(filterd_question)
        linked_question = self.link_slot.handle(analyzed_question)
        response = self.query_slot.handle(linked_question)
        response = self.answer_slot.handle(response)

        return response
